package com.qf.efserver.sport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qf.common.core.entity.ActivityRecords;
import com.qf.common.core.entity.SportDay;
import com.qf.common.core.utils.UserUtils;
import com.qf.common.redis.utils.RedisUtils;
import com.qf.efserver.sport.mapper.SportDayMapper;
import com.qf.efserver.sport.mapper.SportMapper;
import com.qf.efserver.sport.param.SportDayParam;
import com.qf.efserver.sport.param.SportDistanceParam;
import com.qf.efserver.sport.param.SportDurationParam;
import com.qf.efserver.sport.param.TargetStepsParam;
import com.qf.efserver.sport.service.SportDayService;
import com.qf.efserver.sport.vo.SportWeekVO;
import lombok.RequiredArgsConstructor;

import org.apache.http.client.utils.DateUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SportDayServiceImpl implements SportDayService {
    public final SportDayMapper sportDayMapper;
    public final SportMapper sportMapper;

    /**
     * 查询本周运动数据
     * @param weekId
     * @return
     */
    @Override
    public SportDayParam selectWeek(Integer weekId) {
        // 查询本周运动数据
        List<SportDay> sportDays = sportDayMapper.selectWeek(weekId, UserUtils.getUid());
        // 计算总距离，总运动时长，总步数，总消耗卡路里
        Double distance = sportDays.stream().mapToDouble(item -> item.getDistance()).sum();
        Integer durationSum = sportDays.stream().mapToInt(item -> item.getDuration()).sum();
        int stepsSum = sportDays.stream().mapToInt(item -> item.getSteps()).sum();
        int caloriesBurnedSum = sportDays.stream().mapToInt(item -> item.getCaloriesBurned()).sum();
        List<SportWeekVO> sportWeekVOS = sportDays.stream().map(item -> {
            SportWeekVO sportWeekVO = new SportWeekVO();
            sportWeekVO.setDuration(item.getDuration());
            //查询当天日期
            sportWeekVO.setTodayTime(item.getTodayTime());
            return sportWeekVO;

        }).collect(Collectors.toList());
        SportDayParam sportDayParam = sportDayMapper.selectWeekCal(weekId, UserUtils.getUid());
        sportDayParam.setDistance(distance);
        sportDayParam.setDurationAvg(durationSum/7);
        sportDayParam.setSteps(stepsSum);
        sportDayParam.setCaloriesBurneds(caloriesBurnedSum);
        sportDayParam.setSportWeekVOList(sportWeekVOS);
        // 查询本周进行运动类型数量
        Integer typeCounts = sportMapper.selectActivityTypeCounts(weekId, UserUtils.getUid());
        sportDayParam.setActivityTypeCounts(typeCounts);
        return sportDayParam;
    }

    /**
     * 添加今日运动步数目标或修改今日运动步数目标
     * @param target
     */
    @Override
    public void addTargetSteps(Integer target) {
        String yyyyMMdd = DateUtils.formatDate(new Date(), "yyyyMMdd");

        String key = "target:"+yyyyMMdd;
        //Redis存储今日运动目标
        RedisUtils.hashPut(key, UserUtils.getUid().toString(),target);
        // 设置过期时间
        RedisUtils.expire(key, 24*60*60);
        SportDay sportDay = new SportDay();
        SportDay sportDay1 = sportDayMapper.selectOne(new LambdaQueryWrapper<SportDay>()
                .eq(SportDay::getTodayTime, LocalDate.now()));
        // 判断今日是否有数据
        if (sportDay1==null){
            // 添加今日运动步数目标
            sportDay.setUserId(UserUtils.getUid());
            sportDay.setTargetSteps(target);
            sportDay.setTodayTime(LocalDate.now());
            sportDayMapper.insert(sportDay);
        }else {
            sportDay1.setTargetSteps(target);
            sportDayMapper.updateById(sportDay1);
        }


    }


    /**
     * 查询某日运动步数目标
     * @param localDate
     * @return
     */

    @Override
    public Integer selectTargetSteps(LocalDate localDate) {
        LambdaQueryWrapper<SportDay> lambdaQueryWrapper = new LambdaQueryWrapper<SportDay>()
                .eq(SportDay::getTodayTime, localDate);
        SportDay sportDay = sportDayMapper.selectOne(lambdaQueryWrapper);
        Integer targetSteps = sportDay.getTargetSteps();

        return targetSteps;
    }

    /**
     * 查询今日运动步数目标,今日运动步数，今天运动次数
     * @return
     */
    @Override
    public TargetStepsParam selectTargetParam() {
        String yyyyMMdd = DateUtils.formatDate(new Date(), "yyyyMMdd");
        String key = "target:"+yyyyMMdd;
        // 查询今日运动步数和运动时长
        TargetStepsParam targetStepsParam = new TargetStepsParam();
        SportDay sportDay = sportDayMapper.selectByUidCreateTime(UserUtils.getUid());
        if (sportDay==null){
            targetStepsParam.setDaySteps(0);

            targetStepsParam.setCount(0);
        }else {
            targetStepsParam.setDaySteps(sportDay.getSteps());
            targetStepsParam.setCount(sportMapper.selectDayCount(UserUtils.getUid()));
        }

        if (RedisUtils.hasHashField(key, UserUtils.getUid().toString())){
            targetStepsParam.setTarget((Integer) RedisUtils.hashGet(key, UserUtils.getUid().toString()));
        }else {
            targetStepsParam.setTarget(60000);
        }
        return targetStepsParam;
    }

    /**
     * 添加今日运动距离目标或修改今日运动距离目标
     * @param targetDistance
     */
    @Override
    public void addTargetDistance(Double targetDistance) {

        SportDay sportDay = new SportDay();
        SportDay sportDay1 = sportDayMapper.selectOne(new LambdaQueryWrapper<SportDay>()
                .eq(SportDay::getTodayTime, LocalDate.now()));
        // 判断今日是否有数据
        if (sportDay1==null){
            // 添加今日运动数据
            sportDay.setUserId(UserUtils.getUid());
            sportDay.setTargetDistance(targetDistance);
            sportDay.setTodayTime(LocalDate.now());
            sportDayMapper.insert(sportDay);
        }else {

            sportDay1.setTargetDistance(targetDistance);
            sportDayMapper.updateById(sportDay1);
        }
    }

    /**
     * 查询运动距离，日
     * @param localDate
     * @return
     */
    @Override
    public SportDistanceParam selectDistanceDay(LocalDate localDate) {
        SportDay sportDay = sportDayMapper.selectOne(new LambdaQueryWrapper<SportDay>()
                .eq(SportDay::getTodayTime, localDate));
        if (sportDay!=null){
            SportDistanceParam sportDistanceParam = new SportDistanceParam();
            sportDistanceParam.setDistance(sportDay.getDistance());
            sportDistanceParam.setSteps(sportDay.getSteps());
            sportDistanceParam.setStepsAvg(sportDay.getSteps());
            sportDistanceParam.setCaloriesBurneds(sportDay.getCaloriesBurned());
            return sportDistanceParam;
        }else {
            return new SportDistanceParam();
        }
    }

    /**
     * 查询运动距离，周
     * @param weekId
     * @return
     */
    @Override
    public SportDistanceParam selectDistanceWeek(Integer weekId) {
        List<SportDay> sportDays = sportDayMapper.selectWeek(weekId, UserUtils.getUid());
        if (sportDays!=null){
            SportDistanceParam sportDistanceParam = new SportDistanceParam();
            for (SportDay item : sportDays) {
                sportDistanceParam.setDistance(item.getDistance() + sportDistanceParam.getDistance());
                sportDistanceParam.setSteps(item.getSteps() + sportDistanceParam.getSteps());
                sportDistanceParam.setCaloriesBurneds(item.getCaloriesBurned() + sportDistanceParam.getCaloriesBurneds());
            }
            sportDistanceParam.setStepsAvg(sportDistanceParam.getSteps()/7);
            return sportDistanceParam;
        }else {
            return new SportDistanceParam();
        }
    }

    /**
     * 查询运动距离，月
     * @param monthId
     * @return
     */
    @Override
    public SportDistanceParam selectDistanceMonth(Integer monthId) {
        List<SportDay> sportDays = sportDayMapper.selectMonth(monthId,UserUtils.getUid());
        if (sportDays!=null){
            SportDistanceParam sportDistanceParam = new SportDistanceParam();
            for (SportDay item : sportDays) {
                sportDistanceParam.setDistance(item.getDistance() + sportDistanceParam.getDistance());
                sportDistanceParam.setSteps(item.getSteps() + sportDistanceParam.getSteps());
                sportDistanceParam.setCaloriesBurneds(item.getCaloriesBurned() + sportDistanceParam.getCaloriesBurneds());
            }
            // 获取当前日期
            Calendar calendar = Calendar.getInstance();

            // 获取当前月份的最大天数
            int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            sportDistanceParam.setStepsAvg(sportDistanceParam.getSteps()/daysInMonth);
            return sportDistanceParam;
        }else {
            return new SportDistanceParam();
        }
    }

    /**
     * 查询运动时长，日
     * @param localDate
     * @return
     */
    @Override
    public SportDurationParam selectDurationDay(LocalDate localDate) {

        SportDay sportDay = sportDayMapper.selectOne(new LambdaQueryWrapper<SportDay>()
                .eq(SportDay::getTodayTime, localDate));
        if (sportDay!=null){
            SportDurationParam sportDurationParam = new SportDurationParam();
            sportDurationParam.setDistances(sportDay.getDistance());
            sportDurationParam.setSteps(sportDay.getSteps());
            sportDurationParam.setDurationAvg(sportDay.getDuration());
            sportDurationParam.setCaloriesBurneds(sportDay.getCaloriesBurned());
            return sportDurationParam;
        }else {
            return new SportDurationParam();
        }
    }

    /**
     * 查询运动时长，周
     * @param weekId
     * @return
     */
    @Override
    public SportDurationParam selectDurationWeek(Integer weekId) {
        List<SportDay> sportDays = sportDayMapper.selectWeek(weekId, UserUtils.getUid());
        if (sportDays!=null){
            SportDurationParam sportDurationParam = new SportDurationParam();
            for (SportDay item : sportDays) {
                sportDurationParam.setDistances(item.getDistance() + sportDurationParam.getDistances());
                sportDurationParam.setSteps(item.getSteps() + sportDurationParam.getSteps());
                sportDurationParam.setCaloriesBurneds(item.getCaloriesBurned() + sportDurationParam.getCaloriesBurneds());
                sportDurationParam.setDurations(item.getDuration() + sportDurationParam.getDurations());
            }
            sportDurationParam.setDurationAvg(sportDurationParam.getDurations()/7);
            return sportDurationParam;
        }else {
            return new SportDurationParam();
        }
    }

    /**
     * 查询运动时长，月
     * @param monthId
     * @return
     */
    @Override
    public SportDurationParam selectDurationMonth(Integer monthId) {
        List<SportDay> sportDays = sportDayMapper.selectMonth(monthId,UserUtils.getUid());
        if (sportDays!=null){
            SportDurationParam sportDurationParam = new SportDurationParam();
            for (SportDay item : sportDays) {
                sportDurationParam.setDistances(item.getDistance() + sportDurationParam.getDistances());
                sportDurationParam.setSteps(item.getSteps() + sportDurationParam.getSteps());
                sportDurationParam.setCaloriesBurneds(item.getCaloriesBurned() + sportDurationParam.getCaloriesBurneds());
                sportDurationParam.setDurations(item.getDuration() + sportDurationParam.getDurations());
            }
            // 获取当前日期
            Calendar calendar = Calendar.getInstance();

            // 获取当前月份的最大天数
            int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            sportDurationParam.setDurationAvg(sportDurationParam.getDurations()/daysInMonth);
            return sportDurationParam;
        }else {
            return new SportDurationParam();
        }
    }


}
